package aliyun

import (
	"fmt"
	"github.com/aliyun/aliyun-oss-go-sdk/oss"
	"io"
	"os"
	"strings"
	"time"
)

type CloudConfig struct {
	AccessKeyID     string `json:"access_key_id"`
	AccessKeySecret string `json:"access_key_secret"`
	BucketName      string `json:"bucket_name"`
	BucketDomain    string `json:"bucket_domain"`
	EndPoint        string `json:"end_point"`
	Location        string `json:"location"`
	TemplateID      string `json:"template_id"`
	PipelineId      string `json:"pipeline_id"`
}

var (
	bucketName   = ""
	BucketDomain = ""
	endPoint     = ""
	Avatar       = "avatar"
	Photo        = "photo"
	Video        = "video"
	Other        = "other"
	Static       = "static"
	CA           = "CA"
	IsDebug      = true
	conf         CloudConfig
)

func InitAliyun(conf CloudConfig, isDebug bool) {
	bucketName = conf.BucketName
	BucketDomain = conf.BucketDomain
	endPoint = conf.EndPoint //华东1
	IsDebug = isDebug
}

func createOSS() (*oss.Client, error) {
	client, err := oss.New(endPoint, conf.AccessKeyID, conf.AccessKeySecret,
		func(c *oss.Client) {
			c.Config.IsDebug = IsDebug
			c.Config.HTTPTimeout = oss.HTTPTimeout{
				IdleConnTimeout:  90 * time.Second,
				ConnectTimeout:   30 * time.Second,
				ReadWriteTimeout: 60 * time.Second,
				HeaderTimeout:    60 * time.Second,
				LongTimeout:      300 * time.Second,
			}
		})
	if err != nil {
		err := fmt.Errorf("aliyun cloud start failed, err: %s", err.Error())
		return nil, err
	}
	return client, nil
}

func PutObject(objKey string, reader io.Reader, options ...oss.Option) error {
	client, err := createOSS()
	if err != nil {
		return err
	}
	bucket, err := client.Bucket(bucketName)
	if err != nil {
		return err
	}
	return bucket.PutObject(objKey, reader, options...)
}

func CopyObject(srcObjKey, destObjKey string, options ...oss.Option) error {
	client, err := createOSS()
	if err != nil {
		return err
	}
	bucket, err := client.Bucket(bucketName)
	if err != nil {
		return err
	}
	_, err = bucket.CopyObject(srcObjKey, destObjKey, options...)
	return err
}

func CopyObjectTo(destBucketName, srcObjKey, destObjKey string, options ...oss.Option) error {
	client, err := createOSS()
	if err != nil {
		return err
	}
	bucket, err := client.Bucket(bucketName)
	if err != nil {
		return err
	}
	_, err = bucket.CopyObjectTo(destBucketName, srcObjKey, destObjKey, options...)
	return err
}

func GeneralObjectUrl(objKey string) string {
	if objKey == "" {
		return ""
	}
	return fmt.Sprintf("https://%s/%s", BucketDomain, objKey)
}
func GeneralObjectUrlArr(objKeys []string) (linkArr []string) {
	if len(objKeys) == 0 {
		return
	}
	for _, j := range objKeys {
		if len(j) > 0 {
			str := fmt.Sprintf("https://%s/%s", BucketDomain, j)
			linkArr = append(linkArr, str)
		}
	}
	return
}

func TrimBucketDomain(aliyunLink string) string {
	if strings.Contains(aliyunLink, BucketDomain) {
		index := strings.Index(aliyunLink, ".com/")
		return aliyunLink[index+5:]
	}
	return aliyunLink
}

func DeleteObject(objKey string) error {
	client, err := createOSS()
	if err != nil {
		return err
	}
	bucket, err := client.Bucket(bucketName)
	if err != nil {
		return err
	}
	return bucket.DeleteObject(objKey)
}

func GetObjectCreateTime(objKey string) (error, string) {
	client, err := createOSS()
	if err != nil {
		return err, ""
	}
	bucket, err := client.Bucket(bucketName)
	if err != nil {
		return err, ""
	}
	// 获取文件元信息。
	props, err := bucket.GetObjectDetailedMeta(objKey)
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}
	return nil, props.Get("Last-Modified")
}

func IsObjectExist(objKey string) (bool, error) {
	client, err := createOSS()
	if err != nil {
		return false, err
	}
	bucket, err := client.Bucket(bucketName)
	if err != nil {
		return false, err
	}
	return bucket.IsObjectExist(objKey)
}
